package com.jnc.pay.biz.wechatpay.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import com.jnc.pay.biz.common.mapper.TradeMapper;
import com.jnc.pay.biz.common.model.Contract;
import com.jnc.pay.biz.common.model.Trade;
import com.jnc.pay.biz.common.model.Trans;
import com.jnc.pay.biz.common.service.CommonService;
import com.jnc.pay.biz.common.service.impl.AbstractWechatPay;
import com.jnc.pay.biz.common.vo.*;
import com.jnc.pay.constant.BizConstant;
import com.jnc.pay.constant.WechatPayConstant;
import com.jnc.pay.core.config.redis.RedisStore;
import com.jnc.pay.core.model.BaseResp;
import com.jnc.pay.core.model.RespCode;
import com.jnc.pay.util.pay.WechatPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Map;

/**
 * @Auther: jjn
 * @Date: 2020/6/29 16:10
 * @Desc: 微信JSAPI支付（JSAPI）
 * 适用公众号内、小程序、微信客户端H5支付业务
 */
@Slf4j
@Service
public class WechatPayJSAPI extends AbstractWechatPay {

    @Autowired
    RedisStore redisStore;
    @Autowired
    WechatPayUtil wechatPayUtil;
    @Resource
    TradeMapper tradeMapper;
    @Autowired
    CommonService commonService;


    @Override
    public BaseResp<Map<String, Object>> doPay(PayReq req) {
        Map<String, Object> map = MapUtil.newHashMap();
        //2、组装微信JSAPI，支付请求参数
        String xmlReq = fillPayReq(map, req);

        //3、组装微信JSAPI，支付响应参数
        return fillPayResp(xmlReq, req);
    }

    @Override
    public BaseResp<Map<String, Object>> doQuery(QueryReq req) {
        Map<String, Object> map = MapUtil.newHashMap();
        //2、组装微信JSAPI，查询请求参数
        String xmlReq = fillQueryReq(map, req);

        //3、组装微信JSAPI，查询响应参数
        return fillQueryResp(xmlReq, req);
    }

    @Override
    public BaseResp<Map<String, Object>> doRefund(RefundReq req) {
        Map<String, Object> map = MapUtil.newHashMap();
        //获取支付订单数据
        Trade trade = tradeMapper.getTradeById(req.getTradeId());
        if(trade == null){
            log.warn("[Wechatpay.JSAPI] No valid refund orders, req: {}", req);
            return BaseResp.fail("no valid refund orders");
        }
        req.setTotalFee(trade.getTotalFee());
        req.setTradeNo(trade.getTradeNo());
        req.setAppOrderId(trade.getAppOrderId());
        if(req.getRefundFee().intValue() != trade.getTotalFee().intValue()){
            log.warn("[Wechatpay.JSAPI] The order amount is inconsistent with the refund amount, req: {}", req);
            return BaseResp.fail("refund fee mismatch");
        }
        //2、组装微信APP，退款请求参数
        String xmlReq = fillRefundReq(map, req);

        //3、组装微信APP，退款响应参数
        return fillRefundResp(xmlReq, req);
    }

    @Override
    public BaseResp<Map<String, Object>> doRefundQuery(RefundQueryReq req) {
        Map<String, Object> map = MapUtil.newHashMap();
        //2、组装微信APP，查询请求参数
        String xmlReq = fillRefundQueryReq(map, req);

        //3、组装微信APP，查询响应参数
        return fillRefundQueryResp(xmlReq, req);
    }

    @Override
    protected void addTrade(PayReq req) {
        commonService.addTrade(req);
    }

    @Override
    protected void addRefund(RefundReq req) {
        commonService.addRefund(req);
    }

    @Override
    protected void addContract(ContractReq req) {
        Contract model = new Contract();
        BeanUtil.copyProperties(req, model);
        model.setContractStatus(BizConstant.WAIT_CONTRACT);
        commonService.addContract(model);
    }

    @Override
    public BaseResp<Map<String, Object>> doEnterPayChange(PayChangeReq req) {
        Map<String, Object> map = MapUtil.newHashMap();
        //2、组装微信企业付款到零钱请求参数
        String xmlReq = fillPayChangeReq(map, req);
        //3、组装微信企业付款到零钱响应参数
        Map<String, Object> respMap = MapUtil.newHashMap();
        respMap.put("trans_id", req.getTransId());
        respMap.put("app_trans_id", req.getAppTransId());
        respMap.put("out_app_id", req.getAppId());
        BaseResp<Map<String, Object>> respDefault = postAbSSL(WechatPayConstant.WECHAT_GATEWAY + WechatPayConstant.WECHAT_PAY_CHANGE, xmlReq, req.getWechatpayConfig());
        Map<String, Object> data = respDefault.getData();
        String payment_no = MapUtil.getStr(data, "payment_no");
        Trans model = new Trans();
        BeanUtil.copyProperties(req, model);
        model.setTransStatus(BizConstant.TRANS_FAIL);
        model.setTransNo(payment_no);
        model.setFinishTime((int) (System.currentTimeMillis() / 1000));
        if(respDefault.getCode() == RespCode.SUCCESS.getCode()){
            model.setTransStatus(BizConstant.TRANS_BIZ_COMPLETE);
            respMap.put("payment_time", MapUtil.getStr(data, "payment_time"));
            respDefault.setData(respMap);
        }else{
            String err_code = MapUtil.getStr(data, "err_code");
            String err_code_des = MapUtil.getStr(data, "err_code_des");
            model.setErorrCode(err_code);
            model.setErorrMsg(err_code_des);
        }
        commonService.addTrans(model);
        respDefault.setData(respMap);
        return respDefault;
    }

    @Override
    public BaseResp<Map<String, Object>> doContract(ContractReq req) {
        Map<String, Object> map = MapUtil.newHashMap();
        //2、组装微信签约请求参数
        String urlReq = fillContractReq(map, req);
        //公众号签约为同步返回拼接url，此处新增签约数据
        addContract(req);
        Map<String, Object> respMap = MapUtil.newHashMap();
        respMap.put("request_url", urlReq);
        return BaseResp.resp(RespCode.SUCCESS.getCode(), RespCode.SUCCESS.getDesc(), respMap);
    }

    /**
     * 签约、解约状态查询
     * @param req
     * @return
     */
    public BaseResp<Map<String, Object>> doContractQuery(ContractQueryReq req){
        Map<String, Object> map = MapUtil.newHashMap();
        //2、组装微信签约查询请求参数
        String xmlReq = fillContractQueryReq(map, req);
        //3、组装微信签约查询响应参数
        return fillContractQueryResp(xmlReq, req);
    }

    /**
     * 解约
     * @param req
     * @return
     */
    public BaseResp<Map<String, Object>> doTermination(TerminationReq req){
        Map<String, Object> map = MapUtil.newHashMap();
        //2、组装微信解约请求参数
        String xmlReq = fillTerminationReq(map, req);
        //3、组装微信解约响应参数
        return fillTerminationResp(xmlReq, req);
    }

    /**
     * 代扣
     * @param req
     * @return
     */
    public BaseResp<Map<String, Object>> doWithhold(WithholdReq req){
        Map<String, Object> map = MapUtil.newHashMap();
        //2、组装微信代扣请求参数
        String xmlReq = fillWithholdReq(map, req);
        //3、组装微信代扣响应参数
        return fillWithholdResp(xmlReq, req);
    }

}
